home *** CD-ROM | disk | FTP | other *** search
/ Suzy B Software 2 / Suzy B Software CD-ROM 2 (1994).iso / extras / programm / a56 / src / main.c < prev    next >
C/C++ Source or Header  |  1995-04-27  |  8KB  |  457 lines

  1. /*******************************************************
  2.  *
  3.  *  a56 - a DSP56001 assembler
  4.  *
  5.  *  Written by Quinn C. Jensen
  6.  *  July 1990
  7.  *
  8.  *******************************************************\
  9.  
  10. /*
  11.  * Copyright (C) 1990-1994 Quinn C. Jensen
  12.  *
  13.  * Permission to use, copy, modify, distribute, and sell this software
  14.  * and its documentation for any purpose is hereby granted without fee,
  15.  * provided that the above copyright notice appear in all copies and
  16.  * that both that copyright notice and this permission notice appear
  17.  * in supporting documentation.  The author makes no representations
  18.  * about the suitability of this software for any purpose.  It is
  19.  * provided "as is" without express or implied warranty.
  20.  *
  21.  */
  22. static char *Copyright = "Copyright (C) 1990-1994 Quinn C. Jensen";
  23.  
  24. /*
  25.  *  main.c - The "main" code for the assembler.
  26.  *
  27.  */
  28.  
  29. #include "a56.h"
  30.  
  31. #define MAX 1024
  32.  
  33. int pass;
  34. int error;
  35. extern unsigned long pc;
  36. extern int seg;
  37. BOOL binary_listing = FALSE;
  38. BOOL list_includes = FALSE;
  39. FILE *obj = NULL;
  40. extern BOOL list_on;
  41. BOOL list_on_next = TRUE;
  42. char *alloc();
  43.  
  44. main(argc,argv)
  45. int argc;
  46. char *argv[];
  47. {
  48.     int i;
  49.     extern char *optarg;
  50.     extern int optind;
  51.     int c;
  52.     char *output_file = "a56.out";
  53.     char *input_file;
  54.  
  55.     while((c = getopt(argc, argv, "bldo:")) != EOF) switch (c) {
  56.         case 'b':
  57.             binary_listing++;
  58.             break;
  59.         case 'l':
  60.             list_includes++;
  61.             break;
  62.         case 'd':
  63.             ldebug++;
  64.             break;
  65.         case 'o':
  66.             output_file = optarg;
  67.             break;
  68.         case '?':
  69.         default:
  70.             fatal("usage: a56  [-b]  [-l]  [-d]  [-o output-file]  input-file\n");
  71.     }
  72.     input_file = argv[optind++];
  73.     obj = open_write(output_file);
  74.  
  75.     pc = 0;
  76.     seg = 0;
  77.     pass = 1;
  78.     reset_psects();
  79.     include(input_file);
  80.  
  81.     pc = 0;
  82.     seg = 0;
  83.     pass = 2;
  84.     reset_psects();
  85.     include(input_file);
  86.  
  87.     psect_summary();
  88.     dump_symtab();
  89.     fclose(obj);
  90.     printf("errors=%d\n", error);
  91.     return error ? 1 : 0;
  92. }
  93.  
  94. struct inc inc[MAX_NEST];
  95. int inc_p = 0;
  96. FILE *yyin;
  97.  
  98. include(file)
  99. char *file;
  100. {
  101.     FILE *fp = open_read(file);
  102.  
  103.     inc_p++;
  104.     if(inc_p >= MAX_NEST)
  105.         fatal("%s: include nesting too deep\n", file);
  106.  
  107.     inc[inc_p].file = file;
  108.     inc[inc_p].fp = fp;
  109.     inc[inc_p].line = 1;
  110.  
  111.     list_on_next = TRUE;
  112.     if(inc_p > 1 && NOT list_includes)
  113.         list_on_next = FALSE;
  114.  
  115.     yyin = inc[inc_p].fp;
  116.     if(inc_p == 1)
  117. #ifdef FLEX
  118.     {
  119.         static int started = 0;
  120.         if(started)
  121.             yyrestart(yyin);
  122.         else
  123.             started = 1;
  124.         yyparse();
  125.     }
  126. #else
  127.         yyparse();
  128. #endif
  129. }
  130.  
  131. yywrap()
  132. {
  133.     fclose(inc[inc_p].fp);
  134.     inc_p--;
  135.     list_on = list_on_next = TRUE;
  136.     if(inc_p > 1)
  137.         list_on = list_on_next = FALSE;
  138.     if(inc_p) {
  139.         yyin = inc[inc_p].fp;
  140.         return 0;
  141.     } else {
  142.         return 1;
  143.     }
  144. }
  145.  
  146. struct n
  147. sym_ref(sym)        /* return symbol value or UNDEF if not defined yet */
  148. char *sym;
  149. {
  150.     struct sym *sp, *find_sym();
  151.     struct n result;
  152.  
  153.     result.type = UNDEF;
  154.  
  155.     sp = find_sym(sym);
  156.     if(NOT sp) {
  157.         if(pass == 2) {
  158.             yyerror("%s: undefined symbol", sym);
  159.         }           
  160.         return result;
  161.     }
  162.  
  163.     return sp->n;
  164. }
  165.  
  166. #define HASHSIZE 128
  167.  
  168. #define HASH(sym) (((sym)[0] ^ sym[1]) % HASHSIZE)
  169.  
  170. struct sym *symtab[HASHSIZE];
  171.  
  172. sym_def(sym, type, i, f)
  173. char *sym;
  174. int type;
  175. int i;
  176. double f;
  177. {
  178.     struct sym *sp, **stop, *find_sym();
  179.  
  180.     if(pass == 1) {
  181.         if(find_sym(sym)) {
  182.             pass = 2;                /* what a kludge */
  183.             yyerror("%s: multiply defined symbol", sym);
  184.             pass = 1;
  185.             return;
  186.         }
  187.         stop = &symtab[HASH(sym)];
  188.         sp = NEW(struct sym);
  189.         sp->next = *stop;
  190.         *stop = sp;
  191.         sp->name = strsave(sym);
  192.         sp->n.type = type;
  193.         if(type == INT)
  194.             sp->n.val.i = i & 0xFFFFFF;
  195.         else
  196.             sp->n.val.f = f;
  197.     } else {
  198.         sp = find_sym(sym);
  199.         if(NOT sp)
  200.             fatal("internal error 304\n");
  201.         if(sp->n.type != type ||
  202.             type == INT && sp->n.val.i != (i & 0xFFFFFF) ||
  203.             type == FLT && sp->n.val.f != f)
  204.             yyerror("%s: assembler phase error", sym);
  205.     }        
  206. }
  207.  
  208. struct sym *find_sym(sym)
  209. char *sym;
  210. {
  211.     struct sym *sp, **stop;
  212.  
  213.     stop = &symtab[HASH(sym)];
  214.     for(sp = *stop; sp; sp = sp->next)
  215.         if(strcmp(sp->name, sym) == 0)
  216.             return sp;
  217.         
  218.     return NULL;
  219. }
  220.  
  221. dump_symtab()
  222. {
  223.     struct sym *sp, **stop;
  224.     int i;
  225.  
  226.     printf("\n\
  227. Symbol Table\n\
  228. -------------------------------------\n");
  229. /*
  230. SSSSSSSSSSSSSSSS XXXXXX
  231. SSSSSSSSSSSSSSSS DDDDDDDDD.DDDDDDDDDD
  232. */
  233.  
  234.     for(i = 0, stop = symtab; i < HASHSIZE; i++, stop++) {
  235.         for(sp = *stop; sp; sp = sp->next) {
  236.             if(sp->n.type == INT)
  237.                 printf("%16s %06X\n", sp->name, sp->n.val.i);
  238.             else
  239.                 printf("%16s %.10f\n", sp->name, sp->n.val.f);
  240.         }
  241.     }   
  242. }
  243.  
  244. char *printcode(word)
  245. int word;
  246. {
  247.     static char list[MAX], *lp;
  248.     int i;
  249.  
  250.     word &= 0xFFFFFF;
  251.  
  252.     if(binary_listing) {
  253.         sprintf(list, "%06X<", word);
  254.         for(i = 0, lp = &list[7]; i < 24; i++, lp++) {
  255.             *lp = word & 1 << 23 - i ? '1' : '0';
  256.             if(i && i % 4 == 3)
  257.                 *++lp = i % 8 == 7 ? ' ' : ',';
  258.         }
  259.         lp[-1] = '>';
  260.         lp[0] = '\0';
  261.     } else {
  262.         sprintf(list, "%06X", word);
  263.     }
  264.     return list;
  265. }
  266.  
  267. char *spacespace[2] = {
  268. /*P:XXXX_XXXXXX_*/
  269.  "              ",
  270. /*P:XXXX_XXXXXX(XXXX_XXXX_XXXX_XXXX_XXXX_XXXX)_*/
  271.  "                                             "};
  272. char *spaces(n)
  273. int n;
  274. {
  275.     return spacespace[binary_listing ? 1 : 0] + n;
  276. }
  277.  
  278. extern char segs[];
  279.  
  280. gencode(seg, pc, word)
  281. int seg, pc, word;
  282. {
  283.     fprintf(obj, "%c %04X %06X\n", segs[seg], pc, word & 0xFFFFFF);
  284. }
  285.  
  286. char fixbuf[1024];
  287.  
  288. char *fixstring(s)
  289. char *s;
  290. {
  291.     char *bp = fixbuf;
  292.     int ival;
  293.  
  294.     while(*s) {
  295.         switch (*s) {
  296.             case '\'':
  297.             case '\"':
  298.                 s++;
  299.                 break;
  300.             case '\\':
  301.                 switch (*++s) {
  302.                     case 'b': *bp++ = '\b'; break;
  303.                     case 'r': *bp++ = '\r'; break;
  304.                     case 'f': *bp++ = '\f'; break;
  305.                     case 'n': *bp++ = '\n'; break;
  306.                     case 't': *bp++ = '\t'; break;
  307.                     case '\\': *bp++ = '\\'; break;
  308.                     case '0':
  309.                         ival = 0;
  310.                         while(*s >= '0' && *s <= '9') {
  311.                             ival <<= 3;
  312.                             ival += *s++ - '0';
  313.                         }
  314.                         *bp++ = ival;
  315.                         break;
  316.                 }
  317.                 break;
  318.             default:
  319.                 *bp++ = *s++;
  320.                 break;
  321.         }
  322.     }
  323.     *bp = '\0';
  324.     return fixbuf;
  325. }
  326.  
  327. #define ONE 0x4000000
  328.  
  329. makefrac(s)
  330. char *s;
  331. {
  332.     int frac = 0, div = 1;
  333.     int scale = 1;
  334.  
  335.     while(*s) {
  336.         switch(*s) {
  337.             case '-':
  338.                 scale = -1;
  339.                 break;
  340.             case '.':
  341.                 div = 10;
  342.                 break;
  343.             default:
  344.                 frac += (*s - '0') * scale * ONE / div;
  345.                 div *= 10;
  346.                 break;
  347.         }
  348.         s++;
  349.     }
  350.  
  351.     return frac + scale * 4 >> 3 & 0xFFFFFF;
  352. }
  353.  
  354. /***************** psect stuff ************************/
  355.  
  356. struct psect *ptop = NULL, *cur_psect = NULL;
  357.  
  358. reset_psects()
  359. {
  360.     struct psect *pp;
  361.  
  362.     for(pp = ptop; pp; pp = pp->next) {
  363.         pp->pc = pp->bottom;
  364.     }
  365.  
  366.     set_psect(NULL);
  367. }
  368.  
  369. psect_summary()
  370. {
  371.     printf("\nSummary of psect usage\n\n");
  372.  
  373.     printf("\
  374.                  section seg base last top      used       avail    total\n\
  375. -------------------------------------------------------------------------\n");
  376. /*
  377. SSSSSSSSSSSSSSSSSSSSSSSS  X  FFFF FFFF FFFF 99999 100%  99999 100%  99999
  378. */
  379.  
  380.     summarize(ptop);    /* do it recursively to place back in order */
  381.     printf("\n");
  382. }
  383.  
  384. summarize(pp)
  385. struct psect *pp;
  386. {
  387.     int used = pp->pc - pp->bottom;
  388.     int avail = pp->top - pp->pc;
  389.     int of = pp->top - pp->bottom;
  390.  
  391.     if(pp == NULL)
  392.         return;
  393.  
  394.     summarize(pp->next);
  395.  
  396.     printf("%24.24s  %c  %04X %04X %04X %5d %3d%%  %5d %3d%%  %5d\n",
  397.         pp->name, segs[pp->seg], pp->bottom, pp->pc, pp->top,
  398.         used, of ? used * 100 / of : 0, avail, of ? avail * 100 / of : 0,
  399.         of);
  400. }
  401.  
  402. struct psect *find_psect(name)
  403. char *name;
  404. {
  405.     struct psect *pp;
  406.  
  407.     for(pp = ptop; pp; pp = pp->next)
  408.         if(strcmp(pp->name, name) == 0)
  409.             return pp;
  410.  
  411.     return NULL;
  412. }
  413.  
  414. set_psect(pp)
  415. struct psect *pp;
  416. {
  417.     cur_psect = pp;
  418. }
  419.  
  420. check_psect(seg, pc)
  421. int seg;
  422. unsigned int pc;
  423. {
  424.     if(cur_psect) {
  425.         if(seg == cur_psect->seg && pc >= cur_psect->bottom && 
  426.             pc <= cur_psect->top) {
  427.             cur_psect->pc = pc;
  428.             return TRUE;
  429.         } else {
  430.             return FALSE;
  431.         }
  432.     } else {
  433.         return TRUE;
  434.     }
  435. }
  436.  
  437. struct psect *new_psect(name, seg, bottom, top)
  438. char *name;
  439. int seg;
  440. unsigned int bottom, top;
  441. {
  442.     struct psect *pp = find_psect(name);
  443.  
  444.     if(NOT pp) {
  445.         pp = (struct psect *)alloc(sizeof *pp);
  446.         pp->next = ptop;
  447.         ptop = pp;
  448.         pp->name = strsave(name);
  449.         pp->seg = seg;
  450.         pp->pc = bottom;
  451.     }
  452.     pp->bottom = bottom;
  453.     pp->top = top;
  454.  
  455.     return pp;
  456. }
  457.